<?php
namespace router;

use InvalidArgumentException;

class Context {
	
	private $elements;
	/**
	 * Tells which element is controller name (not full controller name with path).
	 * @var int
	 */
	private $position;
	
	/**
	 * Tells where controller path starts
	 * @var int
	 */
	private $offset;
	
	/**
	 *
	 * @param string $url
	 * @throws InvalidArgumentException
	 */
	function __construct($url, $position = 0, $offset = 0) {
		if (!is_string($url))
			throw new InvalidArgumentException("url has to be a string");
		if ($url == null)
			throw new InvalidArgumentException("url cannot be empty");
		
		//cut off starting end ending slash
		$this->elements = explode("/", preg_replace("/(^\/)|(\/$)/", "", $url));
		$this->position = intval($position);
		$this->offset = intval($offset);
		
		if (count($this->elements) <= $position)
			throw new InvalidArgumentException("position ($position) has to be lower than elements count in url ($url)");
	}
	
	/**
	 * Returns full controller name, including path (or namespace)
	 * @return string
	 */
	function getController() {
		return implode("/", array_slice($this->elements, $this->offset, $this->position - $this->offset + 1));
	}
	
	/**
	 * Returns just controller name (without path or namespace)
	 * @return string
	 */
	function getControllerName() {
		return $this->elements[$this->position];
	}
	
	/**
	 * 
	 * @return int
	 */
	function getPosition() {
		return $this->position;
	}
	
	function getOffset() {
		return $this->offset;
	}
	
	function getUrl() {
		return implode('/', $this->elements);
	}
	
	/**
	 * @return string or NULL if none
	 */
	function getAction() {
		return $this->elements[1 + $this->position] ? $this->elements[1 + $this->position] : NULL;
	}
	
	/**
	 * 
	 * @param int $index
	 * @return string or NULL in no such argument
	 */
	function getArgument($index) {
		return $this->elements[$index + 2 + $this->position] ? $this->elements[$index + 2 + $this->position] : NULL;
	}
	
	function getArguments() {
		return array_slice($this->elements, 2 + $this->position);
	}
	
	function __toString() {
		return self::getUrl();
	}
	
	function getElement($index) {
		if ($index >= count($this->elements) || $index < 0)
			throw new InvalidArgumentException("out of bounds, index '$index' has to be >= 0 and < elements count");
		return $this->elements[$index];
	}
}